package com.varabyte.kobweb.core

import androidx.compose.runtime.*
import com.varabyte.kobweb.compose.css.*
import org.jetbrains.compose.web.css.*

/**
 * An annotation which identifies a [Composable] function as one which will be used as the root skeleton for every
 * page.
 *
 * The method should take a `content: @Composable () -> Unit` parameter.
 *
 * If no method is annotated `@App` then a reasonable default will be used ([KobwebApp] at a bare minimum, or possibly
 * `SilkApp` if using the silk library). Of course, your own custom app method can compose these functions if it wishes
 * to:
 *
 * ```
 * object SiteStyleSheet : StyleSheet() {
 *    /* ... global styles here, for example fonts or site-wide line spacing ... */
 * }
 *
 * @App
 * @Composable
 * fun AppEntry(content: @Composable () -> Unit) {
 *   KobwebApp {
 *     Style(SiteStyleSheet)
 *     Box(Modifier.fillMaxSize().backgroundColor(Colors.Magenta)) {
 *       content()
 *     }
 *   }
 * }
 * ```
 *
 * There must either be **no methods** or **just a single method** marked with this annotation. If Kobweb encounters
 * more than one `@App` annotation, it will log an error and discard duplicates arbitrarily.
 *
 * Finally, it is an error to tag a method with `@App` inside a Kobweb library module. Users can only use it to tag a
 * method in the application module.
 */
@Target(AnnotationTarget.FUNCTION)
annotation class App

@Composable
fun KobwebApp(content: @Composable () -> Unit) {
    Style(DefaultStyleSheet)
    content()
}

object DefaultStyleSheet : StyleSheet() {
    init {
        layer("reset") {
            "html, body" style {
                // Allow our app to stretch the full screen
                padding(0.px)
                margin(0.px)
            }

            "*" style {
                // See also: https://css-tricks.com/box-sizing
                boxSizing("border-box")
            }
        }
    }
}
